﻿function PageButler(colLeftSelector, colRightSelector,
                    dataTablesSelector, dataTablesAjaxSource, dataTablesAoColumns, mnuCrudHeaderText, mnuCrudDeleteText, mnuCrudEditText, mnuCrudDetailsText,
                    urlController_Create, urlController_CreateSubmit, urlController_DeleteSubmit, deleteConfirmDialogParams, urlController_Details, urlController_EmptyFormWithAntiForgeryToken, urlController_Edit, urlController_EditSubmit) {

    /*This class is responsible for */
    var base = this;
    
    var btlLayout = new LayoutButler(colLeftSelector, colRightSelector);
    var btlCRUD = new CRUDFormButler(urlController_Create, urlController_CreateSubmit, urlController_DeleteSubmit, deleteConfirmDialogParams, urlController_Details, urlController_EmptyFormWithAntiForgeryToken, urlController_Edit, urlController_EditSubmit);
    var btlDataTables = new DataTablesButler(dataTablesSelector, dataTablesAjaxSource, dataTablesAoColumns, mnuCrudHeaderText, mnuCrudDeleteText, mnuCrudEditText, mnuCrudDetailsText, btlCRUD);

    function Initiate() {
        btlLayout.ClearColRight();
        btlLayout.Initiate();
        btlDataTables.Initiate();

        btlCRUD.CallCreate_EmptyFormWithAntiForgeryToken();
    }
    
    function UserDoneInEditViewHandler(e) {
        btlLayout.ClearColRight();
        btlCRUD.CallCreate_EmptyFormWithAntiForgeryToken();
        btlLayout.UnprotectColLeft();
        btlDataTables.RefreshDataTable();
    }
    
    
    /*events to be consumed*/
    $(document).on('btnCreateNew_Click', function() {
        btlCRUD.CallCreateController();
    });
    
    $(document).on('EmptyFormWithAntiForgeryTokenController_CallComplete', function (e) {
        var domWithIdOnFormTag = btlLayout.DOMWithIdOnFormTag(e.response, e.idAttributeOfForm);
        btlLayout.InsertContentToColRight(domWithIdOnFormTag);
    });
    $(document).on('EmptyFormWithAntiForgeryTokenController_CallCompleteFail', function (e) {
        alert(e.errorThrown);
    });
    $(document).on('CreateController_CallComplete', function (e) {
        btlLayout.ClearColRight();
        btlLayout.ProtectColLeft();
        var domWithIdOnFormTag = btlLayout.DOMWithIdOnFormTag(e.response, e.idAttributeOfForm);
        btlLayout.InsertContentToColRight(domWithIdOnFormTag);
        var cssClsArrayOfValidationDependentEnabledBtns = ['.btnCreate'];
        btlCRUD.SetSubmitButtonValidationDependentEnabledStatus(e.idAttributeOfForm, cssClsArrayOfValidationDependentEnabledBtns);
        btlCRUD.AddClickHandler_btnCancel(e.idAttributeOfForm);
        btlCRUD.AddClickHandler_btnCreate(e.idAttributeOfForm);
    });
    $(document).on('CreateController_CallCompleteFail', function(e) {
         UserDoneInEditViewHandler();
    });
    $(document).on('CreateSubmit_Completed', function(e) {
        UserDoneInEditViewHandler();
    });
    $(document).on('CreateSubmit_CompleteFail', function(e) {
        UserDoneInEditViewHandler();
    });
    $(document).on('DeleteSubmit_Completed', function(e) {
        UserDoneInEditViewHandler();
    });
    $(document).on('DeleteSubmit_CompleteFail', function(e) {
        UserDoneInEditViewHandler();
    });
    $(document).on('EditController_CallComplete', function (e) {
        btlLayout.ClearColRight();
        btlLayout.ProtectColLeft(); 
        var domWithIdOnFormTag = btlLayout.DOMWithIdOnFormTag(e.response, e.idAttributeOfForm);
        btlLayout.InsertContentToColRight(domWithIdOnFormTag);
        var cssClsArrayOfValidationDependentEnabledBtns = ['.btnEdit'];
        btlCRUD.SetSubmitButtonValidationDependentEnabledStatus(e.idAttributeOfForm, cssClsArrayOfValidationDependentEnabledBtns);
        btlCRUD.AddClickHandler_btnCancel(e.idAttributeOfForm);
        btlCRUD.AddClickHandler_btnEdit(e.idAttributeOfForm);
    });
    $(document).on('EditController_CallCompleteFail', function(e) {
        UserDoneInEditViewHandler();
    });
    $(document).on('EditSubmit_Completed', function (e) {
        UserDoneInEditViewHandler();
    });
    $(document).on('EditSubmit_CompleteFail', function(e) { alert(e.textStatus); });
    $(document).on('DetailsController_CallComplete', function (e) {
        btlLayout.ClearColRight();
        btlLayout.ProtectColLeft(); 
        var domWithIdOnFormTag = btlLayout.DOMWithIdOnFormTag(e.response, e.idAttributeOfForm);
        btlLayout.InsertContentToColRight(domWithIdOnFormTag);
        btlCRUD.AddClickHandler_btnDelete(e.idItem, e.idAttributeOfForm);
        btlCRUD.AddClickHandler_btnDone(e.idAttributeOfForm);
    });
    $(document).on('DetailsController_CallCompleteFail', function (e) { alert(e.textStatus); });
    $(document).on('UserCancelEdit', function (e) {
        UserDoneInEditViewHandler(e);
    });
    $(document).on('UserDoneEditView', function (e) {
        UserDoneInEditViewHandler();
    });
    $(document).on('TableSourceDataChanged', btlDataTables.RefreshDataTable); //we need to refresh the datatable when the table source data has been changed

    $(document).ready(Initiate());
}

function DataTablesButler(dataTablesSelector, sAjaxSource, aoColumns, mnuCrudHeaderText, mnuCrudDeleteText, mnuCrudEditText, mnuCrudDetailsText,objCRUDButler) {
    
    var base = this;
    
    this.oTable = null;
    
    this.Initiate = function () {
        var initiatedTable = $(dataTablesSelector).dataTable({
                            'bServerSide': true,
                            'sAjaxSource': sAjaxSource,
                            'bProcessing': true,
                            'aoColumns': aoColumns,           /*The first column "ID" is always leftmost and should always have the { "bVisible": false }-property!*/
                            'fnDrawCallback': function () {
                                /* This function is called on every 'draw' event, and allows you to dynamically 
                                   modify any aspect you want about the created DOM.*/
                                
                                $(dataTablesSelector + ' td').bind('click', function(e) {

                                    var aPos = initiatedTable.fnGetPosition(this);

                                    /* Get the data array for this row */
                                    var aData = initiatedTable.fnGetData(aPos[0]);

                                    /* Update the data array and return the value */
                                    var curEntityId = aData[0];
                                    objCRUDButler.CallDetailsController(curEntityId);
                                });
                                $(dataTablesSelector + ' td').on("mousedown", function(e) {
                                    //do we have a right click?
                                    if (e.which == 3) {

                                        var aPos = initiatedTable.fnGetPosition(this);

                                        /* Get the data array for this row */
                                        var aData = initiatedTable.fnGetData(aPos[0]);
                                        var curEntityId = aData[0];
                                        
                                        //overwrite previously previously defined and static value for mnuCrudHeaderText. Assign a new header based on content in datatable (and the clicked item)
                                        mnuCrudHeaderText = aData.slice(2).join(', ');
                                        
                                        CRUDContextMenu(e,
                                                        mnuCrudHeaderText,
                                                        mnuCrudDeleteText,
                                                        mnuCrudEditText,
                                                        mnuCrudDetailsText,
                                                        function () { objCRUDButler.CallDeleteSubmitWithConfimation(curEntityId); },
                                                        function () { objCRUDButler.CallEditController(curEntityId); },
                                                        function () { objCRUDButler.CallDetailsController(curEntityId); });
                                    }
                                });
                            },
                            "fnRowCallback": function(nRow, aData, iDisplayIndex, iDisplayIndexFull) {
                                /* This function allows you to 'post process' each row after it have been generated 
                                   for each table draw, but before it is rendered on screen. This function might be 
                                   used for setting the row class name etc. */
                                var active = aData[1].toLowerCase() === 'true';
                               
                                switch (active) {
                                case true:
                                    $(nRow).attr({ 'class': 'alert alert-info' });
                                    break;
                                case false:
                                    $(nRow).attr({ 'class': 'alert alert-block' });
                                    break;
                                }
                            }
        });
        base.oTable = initiatedTable;
    };
    
    this.RefreshDataTable = function() {
        // Re-draw the table
        base.oTable.fnReloadAjax();

        //base.oTable.fnClearTable(0);
        base.oTable.fnDraw();
    };

}

function CRUDFormButler(urlController_Create, urlController_CreateSubmit, urlController_DeleteSubmit, deleteConfirmDialogParams, urlController_Details, urlController_EmptyFormWithAntiForgeryToken, urlController_Edit, urlController_EditSubmit) {

    var base = this;

    this.IdAttributeGenerator = function(rawIdAttributeOfFormToBeCreated) {
        //watch out for dangerous characters
        var newID = 'frm' + rawIdAttributeOfFormToBeCreated.replace(/[^a-zA-Z]/g, '');
        return newID;
    };

    function ConfirmDialog(param, callBack) {

        var confirmModal = $('<div class="modal hide fade">' +
                                '<div class="modal-header">' +
                                    '<a class="close" data-dismiss="modal" >&times;</a>' +
                                    '<h3>' + param.heading + '</h3>' +
                                '</div>' +
                                '<div class="modal-body">' +
                                    '<p>' + param.question + '</p>' +
                                '</div>' +
                                '<div class="modal-footer">' +
                                    '<a href="#" class="btn" data-dismiss="modal">' +
                                        param.cancelBtnTxt +
                                    '</a>' +
                                    '<a href="#" id="okBtn" class="btn btn-primary">' +
                                        param.okBtnTxt +
                                    '</a>' +
                                '</div>' +
                             '</div>');

        confirmModal.find('#okBtn').on('click', function(event) {
            callBack();
            confirmModal.modal('hide');
        });

        confirmModal.modal('show');
    }

    this.AddAntiForgeryToken = function (data) {
        data.__RequestVerificationToken = $('input[name=__RequestVerificationToken]').val();
        return data;
    };

    this.CallCreate_EmptyFormWithAntiForgeryToken = function () {
        $.ajax({
            url: urlController_EmptyFormWithAntiForgeryToken,
            type: 'POST',
            cache: false
        })
            .done(
                function (data, textStatus, jqXHR) {
                    var idAttributeOfFormToBeCreated = base.IdAttributeGenerator(urlController_EmptyFormWithAntiForgeryToken);
                    RaiseEmptyFormWithAntiForgeryTokenController_CallComplete(data, textStatus, jqXHR, idAttributeOfFormToBeCreated);
                }
            )
            .fail(
                function (jqXHR, textStatus, errorThrown) {
                    RaiseEmptyFormWithAntiForgeryTokenController_CallCompleteFail(jqXHR, textStatus, errorThrown);
                }
            );
    };

    this.CallCreateController = function() {
        $.ajax({
            url: urlController_Create,
            type: 'POST',
            cache: false
        })
            .done(
                function (data, textStatus, jqXHR) {
                    var idAttributeOfFormToBeCreated = base.IdAttributeGenerator(urlController_Create);
                    RaiseCreateController_CallComplete(data, textStatus, jqXHR, idAttributeOfFormToBeCreated);
                }
            )
            .fail(
                function(jqXHR, textStatus, errorThrown) {
                    RaiseCreateController_CallCompleteFail(jqXHR, textStatus, errorThrown);
                }
            );
    };

    this.CallCreateSubmit = function (formWithDataSelector) {
        //is the form's data valid?
        if ($(formWithDataSelector).valid()) {

            //what data should be collected and submitted to the controller?
            var data = $(formWithDataSelector).serialize();
            $.ajax({
                url: urlController_CreateSubmit,
                type: 'POST',
                cache: false,
                data: base.AddAntiForgeryToken( data )
            })
                .done(
                    function(result, textStatus, jqXHR) {
                        RaiseCreateSubmit_Completed(data, textStatus, jqXHR);
                        RaiseTableSourceDataChanged();
                    }
                )
                .fail(
                    function(jqXHR, textStatus, errorThrown) {
                        RaiseCreateSubmit_CompleteFail(jqXHR, textStatus, errorThrown);
                    }
                );
        }
    };

    this.CallDeleteSubmit = function(id) {
        if (id && id != '') {
            $.ajax({
                url: urlController_DeleteSubmit,
                type: 'POST',
                cache: false,
                data: base.AddAntiForgeryToken( { id: id } )
            })
                .done(
                    function (data, textStatus, jqXHR) {
                        RaiseDeleteSubmit_Completed(data, textStatus, jqXHR);
                        RaiseTableSourceDataChanged();
                    }
                )
                .fail(
                    function (jqXHR, textStatus, errorThrown) {
                        RaiseDeleteSubmit_CompleteFail(jqXHR, textStatus, errorThrown);
                    }
                );
        }
        ;
    };

    this.CallDeleteSubmitWithConfimation = function(id) {
        ConfirmDialog(deleteConfirmDialogParams, function() { base.CallDeleteSubmit(id); });
    };

    this.CallDetailsController = function(id) {
        if (id && id != '') {
            $.ajax({
                url: urlController_Details,
                type: 'POST',
                cache: false,
                data: { id: id }
            })
                .done(
                    function (data, textStatus, jqXHR) {
                        var idAttributeOfFormToBeCreated = base.IdAttributeGenerator(urlController_Details);
                        var idItem = id;
                        RaiseDetailsController_CallComplete(data, textStatus, jqXHR, idAttributeOfFormToBeCreated, idItem);
                    }
                )
                .fail(
                    function(jqXHR, textStatus, errorThrown) {
                        RaiseDetailsController_CallCompleteFail(jqXHR, textStatus, errorThrown);
                    }
                );
        }
        ;
    };

    this.CallEditController = function(id) {
        if (id && id != '') {
            $.ajax({
                url: urlController_Edit,
                type: 'POST',
                cache: false,
                data: { id: id }
            })
                .done(
                    function(data, textStatus, jqXHR) {
                        var idAttributeOfFormToBeCreated = base.IdAttributeGenerator(urlController_Edit);
                        RaiseEditController_CallComplete(data, textStatus, jqXHR, idAttributeOfFormToBeCreated);
                    }
                )
                .fail(
                    function(jqXHR, textStatus, errorThrown) {
                        RaiseEditController_CallCompleteFail(jqXHR, textStatus, errorThrown);
                    }
                );
        }
        ;
    };

    this.CallEditSubmit = function (formWithDataSelector) {
        
        //is the form's data valid?
        if ($(formWithDataSelector).valid()) {

            //what data should be collected and submitted to the controller?
            var data = $(formWithDataSelector).serialize();
            $.ajax({
                url: urlController_EditSubmit,
                type: 'POST',
                cache: false,
                data: base.AddAntiForgeryToken( data )
            })
                .done(
                    function(result, textStatus, jqXHR) {
                        RaiseEditSubmit_Completed(data, textStatus, jqXHR);
                    }
                )
                .fail(
                    function(jqXHR, textStatus, errorThrown) {
                        RaiseEditSubmit_CompleteFail(jqXHR, textStatus, errorThrown);
                    }
                );
                    }
                };

    //buttons on the form
    this.AddClickHandler_btnCancel = function(idAttributeOfForm) {
        var jQuerySelectorOfForm = '#' + idAttributeOfForm;
        $(jQuerySelectorOfForm + ' .btnCancel').on('click', function (e) {
            RaiseUserCancelEdit(idAttributeOfForm);
        });
    };

    this.AddClickHandler_btnCreate = function (idAttributeOfForm) {
        var jQuerySelectorOfForm = '#' + idAttributeOfForm;
        $(jQuerySelectorOfForm + ' .btnCreate').on('click', function (e) {
            base.CallCreateSubmit(jQuerySelectorOfForm);
        });
    };

    this.AddClickHandler_btnEdit = function(idAttributeOfForm) {
        var jQuerySelectorOfForm = '#' + idAttributeOfForm;
        $(jQuerySelectorOfForm + ' .btnEdit').on('click', function (e) {
            base.CallEditSubmit(jQuerySelectorOfForm);
        });
    };

    this.AddClickHandler_btnDelete = function(idItem, idAttributeOfForm) {
        var jQuerySelectorOfForm = '#' + idAttributeOfForm;
        $(jQuerySelectorOfForm + ' .btnDelete').on('click', function(e) {
            base.CallDeleteSubmitWithConfimation(idItem);
        });
    };

    this.AddClickHandler_btnDone = function(idAttributeOfForm) {
        var jQuerySelectorOfForm = '#' + idAttributeOfForm;
        $(jQuerySelectorOfForm + ' .btnDone').on('click', function(e) {
            RaiseUserDoneEditView(idAttributeOfForm);
        });
    };


    //partial view validation and commitment buttons
    this.SetSubmitButtonValidationDependentEnabledStatus = function (idAttributeOfForm, cssClsArrayOfValidationDependentEnabledBtns) {
        var jQuerySelectorOfContainingForm = '#' + idAttributeOfForm;

        function SetCorrectDisabledStatusOnSubmitButtons(jQuerySelectorOfContainingForm, cssClsArrayOfValidationDependentEnabledBtns, formIsInvalid) {
            var array = cssClsArrayOfValidationDependentEnabledBtns;
            $.each(array, function (key, value) {
                cssClsOfBtn = value;
                $(jQuerySelectorOfContainingForm + ' ' + cssClsOfBtn).disabled(formIsInvalid);
            });
        }

        $.validator.setDefaults({
            ignore: '',
            highlight: function (element, errorClass, validClass) {
                //this will happen when validation error occurs
                console.log('Validation FAILED for element [' + $(element).prop("tagName") + ' id='+ $(element).prop('id') + ']');
                var formIsInvalid = true;
                SetCorrectDisabledStatusOnSubmitButtons(jQuerySelectorOfContainingForm, cssClsArrayOfValidationDependentEnabledBtns, formIsInvalid);
            },
            unhighlight: function (element, errorClass, validClass) {
                //this will happen when a previous raised validation error
                var formIsInvalid = false;
                SetCorrectDisabledStatusOnSubmitButtons(jQuerySelectorOfContainingForm, cssClsArrayOfValidationDependentEnabledBtns, formIsInvalid);
            }
        });
        $.validator.unobtrusive.parse(jQuerySelectorOfContainingForm);
    };

    // custom events
    
    function RaiseEmptyFormWithAntiForgeryTokenController_CallComplete(data, textStatus, jqXHR, idAttributeOfForm) {
        $.event.trigger({
            type: 'EmptyFormWithAntiForgeryTokenController_CallComplete',
            response: data,         //data is the response message
            textStatus: textStatus,  //textStatus will always be success in the done function
            jqXHR: jqXHR,        //jqXHR is the raw XMLHttpRequest
            idAttributeOfForm: idAttributeOfForm
        });
    }

    function RaiseEmptyFormWithAntiForgeryTokenController_CallCompleteFail(jqXHR, textStatus, errorThrown) {
        $.event.trigger({
            type: 'EmptyFormWithAntiForgeryTokenController_CallCompleteFail',
            jqXHR: jqXHR,               //jqXHR is the raw XMLHttpRequest
            textStatus: textStatus,     //textStatus will always be success in the done function
            errorThrown: errorThrown    //errorThrown receives the textual portion of the HTTP status, such as "Not Found" or "Internal Server Error."
        });
    }

    function RaiseCreateController_CallComplete(data, textStatus, jqXHR, idAttributeOfForm) {
        $.event.trigger({
            type: 'CreateController_CallComplete',
            response: data,         //data is the response message
            textStatus: textStatus,  //textStatus will always be success in the done function
            jqXHR: jqXHR,        //jqXHR is the raw XMLHttpRequest
            idAttributeOfForm: idAttributeOfForm
        });
    }

    function RaiseCreateController_CallCompleteFail(jqXHR, textStatus, errorThrown) {
        $.event.trigger({
            type: 'CreateController_CallCompleteFail',
            jqXHR: jqXHR,               //jqXHR is the raw XMLHttpRequest
            textStatus: textStatus,     //textStatus will always be success in the done function
            errorThrown: errorThrown    //errorThrown receives the textual portion of the HTTP status, such as "Not Found" or "Internal Server Error."
        });
    }

    function RaiseCreateSubmit_Completed(data, textStatus, jqXHR) {
        $.event.trigger({
            type: 'CreateSubmit_Completed',
            response: data,         //data is the response message
            textStatus: textStatus,  //textStatus will always be success in the done function
            jqXHR: jqXHR        //jqXHR is the raw XMLHttpRequest
        });
    }

    function RaiseCreateSubmit_CompleteFail(jqXHR, textStatus, errorThrown) {
        $.event.trigger({
            type: 'CreateSubmit_CompleteFail',
            jqXHR: jqXHR,               //jqXHR is the raw XMLHttpRequest
            textStatus: textStatus,     //textStatus will always be success in the done function
            errorThrown: errorThrown    //errorThrown receives the textual portion of the HTTP status, such as "Not Found" or "Internal Server Error."
        });
    }

    function RaiseDeleteSubmit_Completed(data, textStatus, jqXHR) {
        $.event.trigger({
            type: 'DeleteSubmit_Completed',
            response: data,         //data is the response message
            textStatus: textStatus,  //textStatus will always be success in the done function
            jqXHR: jqXHR        //jqXHR is the raw XMLHttpRequest
        });
    }

    function RaiseDeleteSubmit_CompleteFail(jqXHR, textStatus, errorThrown) {
        $.event.trigger({
            type: 'DeleteSubmit_CompleteFail',
            jqXHR: jqXHR,               //jqXHR is the raw XMLHttpRequest
            textStatus: textStatus,     //textStatus will always be success in the done function
            errorThrown: errorThrown    //errorThrown receives the textual portion of the HTTP status, such as "Not Found" or "Internal Server Error."
        });
    }

    function RaiseEditController_CallComplete(data, textStatus, jqXHR, idAttributeOfForm) {
        $.event.trigger({
            type: 'EditController_CallComplete',
            response: data,         //data is the response message
            textStatus: textStatus,  //textStatus will always be success in the done function
            jqXHR: jqXHR,        //jqXHR is the raw XMLHttpRequest
            idAttributeOfForm: idAttributeOfForm
        });
    }

    function RaiseEditController_CallCompleteFail(jqXHR, textStatus, errorThrown) {
        $.event.trigger({
            type: 'EditController_CallCompleteFail',
            jqXHR: jqXHR,               //jqXHR is the raw XMLHttpRequest
            textStatus: textStatus,     //textStatus will always be success in the done function
            errorThrown: errorThrown    //errorThrown receives the textual portion of the HTTP status, such as "Not Found" or "Internal Server Error."
        });
    }

    function RaiseEditSubmit_Completed(data, textStatus, jqXHR) {
        $.event.trigger({
            type: 'EditSubmit_Completed',
            response: data,         //data is the response message
            textStatus: textStatus,  //textStatus will always be success in the done function
            jqXHR: jqXHR        //jqXHR is the raw XMLHttpRequest
        });
    }

    function RaiseEditSubmit_CompleteFail(jqXHR, textStatus, errorThrown) {
        $.event.trigger({
            type: 'EditSubmit_CompleteFail',
            jqXHR: jqXHR,               //jqXHR is the raw XMLHttpRequest
            textStatus: textStatus,     //textStatus will always be success in the done function
            errorThrown: errorThrown    //errorThrown receives the textual portion of the HTTP status, such as "Not Found" or "Internal Server Error."
        });
    }

    function RaiseDetailsController_CallComplete(data, textStatus, jqXHR, idAttributeOfForm, idItem) {
        $.event.trigger({
            type: 'DetailsController_CallComplete',
            response: data,         //data is the response message
            textStatus: textStatus,  //textStatus will always be success in the done function
            jqXHR: jqXHR,        //jqXHR is the raw XMLHttpRequest
            idAttributeOfForm: idAttributeOfForm,
            idItem: idItem
        });
    }

    function RaiseDetailsController_CallCompleteFail(jqXHR, textStatus, errorThrown) {
        $.event.trigger({
            type: 'DetailsController_CallCompleteFail',
            jqXHR: jqXHR,               //jqXHR is the raw XMLHttpRequest
            textStatus: textStatus,     //textStatus will always be success in the done function
            errorThrown: errorThrown    //errorThrown receives the textual portion of the HTTP status, such as "Not Found" or "Internal Server Error."
        });
    }

    function RaiseTableSourceDataChanged() {
        $.event.trigger({
            type: 'TableSourceDataChanged'
        });
    }

    function RaiseUserCancelEdit(idAttributeOfForm) {
        $.event.trigger({
            type: 'UserCancelEdit',
            idAttributeOfForm: idAttributeOfForm
        });
    }

    function RaiseUserDoneEditView(idAttributeOfForm) {
        $.event.trigger({
            type: 'UserDoneEditView',
            idAttributeOfForm: idAttributeOfForm
        });
    }
}

function LayoutButler(colLeftSelector, colRightSelector) {
    var base = this;

    this.Initiate = function() {
        base.AddClickHandler_btnCreateNew();
    };
    
    this.SetContainerProtection = function (containerId, enabled) {
        var container = $(containerId);

        container.find('input, select, a').disabled(enabled);

        enabled ? container.block() : container.unblock();
    };

    this.ProtectColLeft = function () {
        base.SetContainerProtection(colLeftSelector, true);
    };

    this.UnprotectColLeft = function () {
        base.SetContainerProtection(colLeftSelector, false);
    };

    this.ClearColRight = function () {
        $(colRightSelector).html('');
    };

    this.DOMWithIdOnFormTag = function(htmlDataString, idAttributeOfForm) {
        //finds a <form /> in a HTML-string and provides it with an id:
        //<form id ='frmExample'/>
        //If not found (or if there are more than one <form />) there will be an exception
        var nbrOfFrmsInContentDOM = $(htmlDataString).find('form').length;

        
        var $manipulatedDomContent = $(htmlDataString);
        if (nbrOfFrmsInContentDOM == 1) {
            //there were exactly one form in contentDOM
            $manipulatedDomContent.find('form').attr('id', idAttributeOfForm);

        } else if (nbrOfFrmsInContentDOM < 1) {
            //we need to check if the provided DOM is a <form /> itself
            if ($manipulatedDomContent.is('form')) {
                $manipulatedDomContent.attr('id', idAttributeOfForm);
            } else {
                $manipulatedDomContent = null;
                throw { 'message': 'No <form /> were present in htmlDataString', 'htmlDataString': htmlDataString };
            }
                
        } else if (nbrOfFrmsInContentDOM > 1) {
            $manipulatedDomContent = null;
            throw { 'message': 'More than 1 <form /> were present in htmlDataString. Couldn\'t assign ID to a specific <form />.', 'htmlDataString': htmlDataString };
        }
        return $manipulatedDomContent;
    };

    this.InsertContentToColRight = function (domContent) {
        $(colRightSelector).append(domContent);
    };
    
    this.AddClickHandler_btnCreateNew = function () {
        var jQuerySelectorOfContainer = colLeftSelector;
        $(jQuerySelectorOfContainer + ' .btnCreateNew').on('click', function (e) {
            RaisebtnCreateNew_Click();
        });
    };
    
    function RaisebtnCreateNew_Click() {
        $.event.trigger({
            type: 'btnCreateNew_Click'
        });
    }
}